package com.auditlog.sql.wrapper;

import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.util.deparser.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static java.util.stream.Collectors.joining;

public class DeleteDeParserWrapper extends DeleteDeParser implements DeParsrWrapper<Delete> {

    private StringBuilder buffer = new StringBuilder();

    List<Integer> validPlaceholder = new ArrayList<>();

    List<Integer> invalidPlaceholder = new ArrayList<>();


    private ExpressionDeParserWrapper expressionVisitor = new ExpressionDeParserWrapper(validPlaceholder, invalidPlaceholder,
            new SelectDeParser(new ExpressionDeParserWrapper(validPlaceholder, invalidPlaceholder, buffer), buffer)
            , buffer);

    public List<Integer> getValidPalceholderIndex() {
        return this.expressionVisitor.getValidPlaceholder();
    }

    public DeleteDeParserWrapper() {
        super();
        expressionVisitor.setBuffer(buffer);
    }

    public DeleteDeParserWrapper(ExpressionDeParser expressionVisitor, StringBuilder buffer) {
        super(expressionVisitor, buffer);
        expressionVisitor.setBuffer(buffer);
        super.setExpressionVisitor(expressionVisitor);
    }

    @Override
    public String deSelectParse(Delete delete, List<String> selectColumns) {
        if (delete.getWithItemsList() != null && !delete.getWithItemsList().isEmpty()) {
            buffer.append("WITH ");
            for (Iterator<WithItem> iter = delete.getWithItemsList().iterator(); iter.hasNext(); ) {
                WithItem withItem = iter.next();
                buffer.append(withItem);
                if (iter.hasNext()) {
                    buffer.append(",");
                }
                buffer.append(" ");
            }
        }
        buffer.append(" SELECT");

        if (delete.getModifierPriority() != null) {
            buffer.append(" ").append(delete.getModifierPriority());
        }

        this.appendSelectColumns(buffer, selectColumns);

        if (delete.isModifierQuick()) {
            buffer.append(" QUICK");
        }
        if (delete.isModifierIgnore()) {
            buffer.append(" IGNORE");
        }
//        if (delete.getTables() != null && !delete.getTables().isEmpty()) {
//            buffer.append(
//                    delete.getTables().stream().map(Table::getFullyQualifiedName).collect(joining(", ", " ", "")));
//        }
//        if (delete.isHasFrom()) {
            buffer.append(" FROM");
//        }
        buffer.append(" ").append(delete.getTable().toString());

        if (delete.getUsingList() != null && !delete.getUsingList().isEmpty()) {
            buffer.append(" USING").append(
                    delete.getUsingList().stream().map(Table::toString).collect(joining(", ", " ", "")));
        }
        if (delete.getJoins() != null) {
            for (Join join : delete.getJoins()) {
                if (join.isSimple()) {
                    buffer.append(", ");
                    new JoinDeParser().deParse(join,expressionVisitor,buffer);
                } else {
                    buffer.append(" ");
                    new JoinDeParser().deParse(join,expressionVisitor,buffer);
                }
            }
        }

        if (delete.getWhere() != null) {
            buffer.append(" WHERE ");
            delete.getWhere().accept(expressionVisitor);
        }

        if (delete.getOrderByElements() != null) {
            new OrderByDeParser(expressionVisitor, buffer).deParse(delete.getOrderByElements());
        }
        if (delete.getLimit() != null) {
            new LimitDeparser(buffer).deParse(delete.getLimit());
        }
        return buffer.toString();
    }
}
